package br.com.massai.model.entity;

import java.util.Map;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

@Entity
@Table(name = "SERVICE_ITEM", uniqueConstraints = @UniqueConstraint(columnNames={"CATEGORY_LEVEL_ID", "DESCRIPTION"}))
@NamedQueries({
	@NamedQuery(name = "ServiceItem.find", query = "SELECT s FROM ServiceItem s"),
	@NamedQuery(name = "ServiceItem.count", query = "SELECT COUNT(s) FROM ServiceItem s"),
	@NamedQuery(name = "ServiceItem.duplicate", query = "SELECT COUNT(s) FROM ServiceItem s WHERE LOWER(s.description) = LOWER(:description)") //s.levelService =:levelService AND s.categoryLevel =:categoryLevel
})
public class ServiceItem extends GenericEntity {

	private static final long serialVersionUID = -6688064389077939768L;

	@Id
	@SequenceGenerator(name = "seqServiceItem", sequenceName = "seq_service_item", allocationSize = 1)
	@GeneratedValue(generator = "seqServiceItem", strategy = GenerationType.SEQUENCE)
	private Long id;

	@Column(name = "DESCRIPTION", length = 255, nullable = false, columnDefinition = "VARCHAR(255)")
	private String description;

	@Column(name = "LEVEL_SERVICE", length = 3, nullable = true, columnDefinition = "VARCHAR(3)")
	private String levelService;

	@ManyToOne(optional = true, cascade = CascadeType.REFRESH)
	@JoinColumn(name = "UNIT_MEASURE_ID", referencedColumnName = "ID")
	private UnitMeasure unitMeasure;

	@ManyToOne(cascade = CascadeType.REFRESH)
	@JoinColumn(name = "CATEGORY_LEVEL_ID", referencedColumnName = "ID")
	private CategoryLevel categoryLevel;
	
	@Column(name = "FLAG_FIXED")
	private boolean flagFixed;

	public ServiceItem() {
		this.unitMeasure = new UnitMeasure();
		this.categoryLevel = new CategoryLevel();
	}
	
	@Override
	public Map<String, Object> getParameters() {
		super.clearParameters();
		
		if(this.description != null && !this.description.isEmpty()){
			super.addClauseWhere("LOWER(s.description) LIKE LOWER(:description)", ConditionType.AND);
			super.addParameters("description", "%" + this.description + "%");
		}

		if(this.levelService != null && !this.levelService.isEmpty()){
			super.addClauseWhere("s.levelService = :levelService", ConditionType.AND);
			super.addParameters("levelService", this.levelService);
		}

		if(this.unitMeasure != null && this.unitMeasure.getId() != null){
			super.addClauseWhere("s.unitMeasure = :unitMeasure", ConditionType.AND);
			super.addParameters("unitMeasure", this.unitMeasure);
		}

		if(this.categoryLevel != null && this.categoryLevel.getId() != null){
			super.addClauseWhere("s.categoryLevel = :categoryLevel", ConditionType.AND);
			super.addParameters("categoryLevel", this.categoryLevel);
		}

		super.addClauseWhere("s.flagFixed =:flagFixed", ConditionType.AND);
		super.addParameters("flagFixed", false);

		return super.getParameters();
	}
	
	@Override
	public boolean equals(Object obj) {
		if(obj == null) return false;
		if(obj instanceof ServiceItem)
			if(((ServiceItem)obj).getId() != null && ((ServiceItem)obj).getId().equals(this.getId())) return true;

		return false;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getLevelService() {
		return levelService;
	}

	public void setLevelService(String levelService) {
		this.levelService = levelService;
	}

	public UnitMeasure getUnitMeasure() {
		return unitMeasure;
	}

	public void setUnitMeasure(UnitMeasure unitMeasure) {
		this.unitMeasure = unitMeasure;
	}

	public CategoryLevel getCategoryLevel() {
		return categoryLevel;
	}

	public void setCategoryLevel(CategoryLevel categoryLevel) {
		this.categoryLevel = categoryLevel;
	}

	public boolean isFlagFixed() {
		return flagFixed;
	}

	public void setFlagFixed(boolean flagFixed) {
		this.flagFixed = flagFixed;
	}
}
